<script>
import { GlButton, GlBadge, GlModal, GlModalDirective, GlSkeletonLoader, GlLink } from '@gitlab/ui';
import * as Sentry from '@sentry/browser';
import { createAlert } from '~/alert';
import { convertToGraphQLId } from '~/graphql_shared/utils';
import { TYPENAME_USER, TYPENAME_MERGE_REQUEST } from '~/graphql_shared/constants';
import aiResponseSubscription from 'ee/graphql_shared/subscriptions/ai_completion_response.subscription.graphql';
import UserFeedback from 'ee/ai/components/user_feedback.vue';
import { __ } from '~/locale';
import aiCommitMessageMutation from '../queries/ai_commit_message.mutation.graphql';

export default {
  apollo: {
    $subscribe: {
      testFile: {
        query: aiResponseSubscription,
        variables() {
          return {
            resourceId: this.resourceId,
            userId: convertToGraphQLId(TYPENAME_USER, window.gon.current_user_id),
          };
        },
        result({ data }) {
          const responseBody = data.aiCompletionResponse?.responseBody;
          const errors = data.aiCompletionResponse?.errors;

          if (errors?.length) {
            createAlert({ message: errors[0] });
            this.$refs.modal.close();
          } else if (responseBody) {
            this.commitMessage = `${responseBody}\n\n-------\n:robot: Commit message generated by AI`;
            this.loadingCommitMessage = false;
          }
        },
      },
    },
  },
  components: {
    GlButton,
    GlBadge,
    GlModal,
    GlSkeletonLoader,
    GlLink,
    UserFeedback,
  },
  directives: {
    GlModal: GlModalDirective,
  },
  props: {
    id: {
      type: Number,
      required: true,
    },
  },
  data() {
    return {
      loadingCommitMessage: false,
      commitMessage: '',
    };
  },
  computed: {
    resourceId() {
      return convertToGraphQLId(TYPENAME_MERGE_REQUEST, this.id);
    },
    actionPrimary() {
      return {
        text: __('Insert'),
        attributes: {
          variant: 'info',
          disabled: this.loadingCommitMessage,
        },
      };
    },
  },
  methods: {
    triggerAiMutation() {
      this.loadingCommitMessage = true;

      try {
        this.$apollo.mutate({
          mutation: aiCommitMessageMutation,
          variables: {
            resourceId: this.resourceId,
          },
        });
      } catch (e) {
        Sentry.captureException(e);

        createAlert({
          message: __('There was an error generating commit message.'),
          primaryButton: {
            text: __('Try again'),
            clickHandler: () => this.triggerAiMutation(),
          },
        });
        this.loadingCommitMessage = false;
      }
    },
    insertCommitMessage() {
      this.$emit('update', this.commitMessage);
    },
  },
  modal: {
    id: 'ai-commit-message',
    actionSecondary: {
      text: __('Cancel'),
      attributes: {
        variant: 'default',
      },
    },
  },
  feedback: {
    eventName: 'generate_commit_message_merge_request',
    link: 'https://gitlab.com/gitlab-org/gitlab/-/issues/408994',
  },
};
</script>

<template>
  <div>
    <gl-button v-gl-modal="$options.modal.id" size="small" @click="triggerAiMutation">
      {{ __('Create AI-generated commit message') }}
    </gl-button>
    <gl-badge class="gl-ml-2" size="sm">
      {{ __('Experiment') }}
    </gl-badge>
    <gl-modal
      ref="modal"
      :aria-label="__('Commit message')"
      :action-primary="actionPrimary"
      :action-secondary="$options.modal.actionSecondary"
      :modal-id="$options.modal.id"
      @primary="insertCommitMessage"
    >
      <template #modal-title>
        {{ __('Commit message') }}
        <gl-badge class="gl-ml-2" size="sm">
          {{ __('Experiment') }}
        </gl-badge>
      </template>
      <gl-skeleton-loader v-if="loadingCommitMessage" :width="250" :lines="4" />
      <template v-else>
        <pre class="commit-row-description gl-mb-3 gl-white-space-pre-line js-toggle-content">
          {{ commitMessage }}
        </pre>
        <user-feedback :event-name="$options.feedback.eventName" />
        <p>
          {{ __('Commit message generated by AI') }}
          &middot;
          <gl-link :href="$options.feedback.link" target="_blank">{{
            __('Leave feedback')
          }}</gl-link>
        </p>
      </template>
    </gl-modal>
  </div>
</template>
